package com.zfzs.post.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.zfzs.post.exception.BadRequestException;
import com.zfzs.post.model.dto.AppPayDTO;
import com.zfzs.post.model.dto.OrderDTO;
import com.zfzs.post.model.vo.GoodsListVO;
import com.zfzs.post.model.vo.GoodsVO;
import com.zfzs.post.model.vo.OrderListVO;
import com.zfzs.post.model.vo.OrderVO;
import com.zfzs.post.modules.address.domain.AgentArea;
import com.zfzs.post.modules.address.service.AgentAreaService;
import com.zfzs.post.modules.agent.domain.AgentWithdrawPwd;
import com.zfzs.post.modules.agent.service.AgentService;
import com.zfzs.post.modules.agent.service.AgentWithdrawPwdService;
import com.zfzs.post.modules.agent.service.dto.AgentDTO;
import com.zfzs.post.modules.domain.AlipayConfig;
import com.zfzs.post.modules.goods.domain.GoodOrder;
import com.zfzs.post.modules.goods.domain.Goods;
import com.zfzs.post.modules.goods.service.GoodOrderService;
import com.zfzs.post.service.AlipayService;
import com.zfzs.post.service.GoodsAboutService;
import com.zfzs.post.service.JwtUserDetailsService;
import com.zfzs.post.service.OrderService;
import com.zfzs.post.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wq
 * @date 2019/10/22 14:26
 * @description
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private GoodOrderService goodOrderService;

    @Autowired
    private GoodsAboutService goodsAboutService;

    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;

    @Autowired
    private AgentAreaService agentAreaService;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private AgentWithdrawPwdService withdrawPwdService;

    @Autowired
    private AgentService agentService;

    @Override
    public List<OrderListVO> getOrderList(Map<String, Object> params) {
        AgentDTO agentInfo = jwtUserDetailsService.getAgentInfo();
        if(params.get("status")==null){
            throw new BadRequestException("参数值不能为空");
        }
        Integer status = Integer.valueOf(params.get("status").toString());
        if (params.get("pageNum") == null) {
            throw new BadRequestException("分页参数不能为空");
        }
        Integer pageNo = Integer.valueOf(params.get("pageNum").toString());
        if (pageNo < 0) {
            throw new BadRequestException("页数不能小于0");
        }

        Page<GoodOrder> page = goodOrderService.getOwnerList(agentInfo.getId(), status, pageNo);
        List<GoodOrder> content = page.getContent();
        System.out.println("订单合集：");
        System.out.println(JSONObject.toJSONString(content));

        List<OrderListVO> orderList = CloneUtils.batchClone(content, OrderListVO.class);
        System.out.println("订单克隆合集：");
        System.out.println(JSONObject.toJSONString(orderList));

        List<String> collect = content.stream().map(GoodOrder::getGoodsId).collect(Collectors.toList());
        System.out.println("商品id合集：");
        System.out.println(JSONObject.toJSONString(collect));

        for (OrderListVO orderVO : orderList) {
            for (String gid : collect) {
                if (gid.equals(orderVO.getGoodsId())) {
                    GoodsVO g = goodsAboutService.getGoodsById(gid);
                    orderVO.setCoverUrl(g.getCoverUrl());
                    orderVO.setModel(g.getModel());
                    orderVO.setLeastNum(g.getLeastNum());
                    orderVO.setPrice(MathUtils.formatToNumber(new BigDecimal(g.getPrice())));
                    orderVO.setTerminalName(g.getTerminalName());
                    orderVO.setGoodName(g.getName());
                }
            }
        }
        return orderList;
    }

    @Override
    public OrderVO getOrderById(Map<String, Object> params) {
        Integer id = Integer.valueOf(params.get("orderId").toString());
        GoodOrder order = goodOrderService.findById(id);

        OrderVO v = CloneUtils.clone(order, OrderVO.class);

        GoodsVO g = goodsAboutService.getGoodsById(order.getGoodsId());
        v.setCoverUrl(g.getCoverUrl());
        v.setCoverUrl(g.getCoverUrl());
        v.setModel(g.getModel());
        v.setLeastNum(g.getLeastNum());
        v.setPrice(MathUtils.formatToNumber(new BigDecimal(g.getPrice())));
        v.setTerminalName(g.getTerminalName());
        v.setGoodName(g.getName());
        AgentArea areaDTO = agentAreaService.findById(order.getAreaId());

        String area = areaDTO.getProvinceName() + areaDTO.getCityName() + areaDTO.getAreaName() + areaDTO.getInfo();
        v.setAcceptName(areaDTO.getNames());
        v.setPhone(areaDTO.getPhone());
        v.setArea(area);
        return v;
    }

    @Override
    public String addOrder(OrderDTO orderDTO) {
        AgentDTO agentInfo = jwtUserDetailsService.getAgentInfo();
        GoodOrder goodOrder = new GoodOrder();

        goodOrder.setAgentId(agentInfo.getId());

        if(orderDTO.getAreaId()==null){
            throw new BadRequestException("请选择收货地址");
        }

        AgentArea area = agentAreaService.findById(orderDTO.getAreaId());
        if (!area.getAgentId().equals(agentInfo.getId())) {
            throw new BadRequestException("地址不正确,该地址不属于您");
        }
        goodOrder.setAreaId(orderDTO.getAreaId());
        goodOrder.setChannelId(agentInfo.getChannelId());
        goodOrder.setStatus(0);
        goodOrder.setGoodsId(orderDTO.getGoodsId());

        Goods g = goodsAboutService.findById(orderDTO.getGoodsId());

        BigDecimal price = new BigDecimal(g.getPrice()).setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal amount = new BigDecimal(orderDTO.getAmount()).setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal totalPrice = price.multiply(new BigDecimal(orderDTO.getGoodsNum()));
        if (totalPrice.compareTo(amount) != 0) {
            throw new BadRequestException("总价不正确");
        }

        goodOrder.setGoodsNum(orderDTO.getGoodsNum());
        goodOrder.setAmount(orderDTO.getAmount());
        String orderNo = StringUtils.getDateString(6);
        goodOrder.setOrderNo(orderNo);
        goodOrder.setTerminalTypeId(g.getTerminalTypeId());

        goodOrderService.create(goodOrder);

        return orderNo;
    }

    @Override
    public void deleteOrder(Map<String, String> params) {
        Integer orderId = Integer.valueOf(params.get("orderId"));

        GoodOrder order = goodOrderService.findById(orderId);

        if (order.getStatus().intValue() == 5) {
            goodOrderService.delete(orderId);
        } else {
            throw new BadRequestException("未失效订单不可删除");
        }


    }


    @Override
    public void updateOrderStatus(GoodOrder order, Integer status) {
        order.setStatus(status);
        goodOrderService.update(order);
    }

    @Override
    public void confirmOrder(Map<String, String> params) {
        Integer orderId = Integer.valueOf(params.get("orderId"));
        //Integer status= Integer.valueOf(params.get("status"));
        GoodOrder order = goodOrderService.findById(orderId);

        if (order.getStatus().intValue() != 3) {
            throw new BadRequestException("订单状态不正确");
        }

        updateOrderStatus(order, 4);
    }

    @Override
    public void cancelOrder(Map<String, String> params) {
        Integer orderId = Integer.valueOf(params.get("orderId"));
        GoodOrder order = goodOrderService.findById(orderId);

        if (order.getStatus().intValue() != 1) {
            throw new BadRequestException("订单状态不正确");
        }
        updateOrderStatus(order, 5);
    }

    @Override
    public String appPay(AppPayDTO dto) {
        AgentDTO agentInfo = jwtUserDetailsService.getAgentInfo();
        Long channelId = agentInfo.getChannelId();
        Long agentId = agentInfo.getId();
        String orderNo = dto.getOrderNo();
        String payType = dto.getPayType();
        String password = dto.getPassword();
        BigDecimal payPrice = dto.getPayPrice();
        if (agentInfo.getIsEffective() == 0) {
            throw new BadRequestException("您还未完成实名认证");
        }
        GoodOrder order = goodOrderService.findByOrderNo(orderNo);
        if (order == null) {
            throw new BadRequestException("未查询到订单信息");
        }
        if (!order.getAgentId().equals(agentId)) {
            throw new BadRequestException("此订单不属于您");
        }
        //查询商品信息
        GoodsVO goods = goodsAboutService.getGoodsById(order.getGoodsId());
        if (goods == null) {
            throw new BadRequestException("未查询到所支付的商品信息");
        }
        BigDecimal amount = new BigDecimal(order.getAmount()).setScale(2,BigDecimal.ROUND_HALF_UP);
        if (amount.compareTo(payPrice) != 0) {
            throw new BadRequestException("支付价格不一致");
        }
        Integer status = order.getStatus();
        if (status >= 2) {
            throw new BadRequestException("支付失败，该订单完成支付或者已经失效");
        }
        if(order.getPayState() >= 2){
            throw new BadRequestException("该订单已经完成支付");
        }
       /* //校验支付密码
        AgentWithdrawPwd withdrawPwd = withdrawPwdService.findById(agentId);
        if (withdrawPwd == null) {
            throw new BadRequestException("您还未设置支付密码");
        }
        String salt = withdrawPwd.getSalt();
        if (withdrawPwd.getPwd() == null || salt == null) {
            throw new BadRequestException("您还未设置支付密码");
        }
        if (!withdrawPwd.getPwd().equals(AesUtil.aesEncrypt(password + salt, AesUtil.encodeRules))) {
            throw new BadRequestException("提现密码错误");
        }*/
        String res = "";
        switch (payType) {
            case "ALI":
                //查询支付信息
                AlipayConfig alipayConfig = alipayService.findById(channelId);
                if (alipayConfig == null) {
                    throw new BadRequestException("未查询到渠道支付宝信息");
                }
                Map<String, Object> map = new HashMap<>();
                map.put("body", goods.getName());
                map.put("subject", goods.getName());
                map.put("order_no", orderNo);
                map.put("amount", payPrice);
                try {
                    res = AliPay.Pay(map, alipayConfig);
                } catch (Exception e) {
                    throw new BadRequestException("900", "支付失败，" + e.getMessage());
                }
                if (StringUtils.isBlank(res)) {
                    throw new BadRequestException("900", "启用支付宝接口失败");
                }
                break;
            default:
                throw new BadRequestException("900", "支付类型错误");
        }
        //修改订单信息
        //order.setPayType(1);
        //goodOrderService.update(order);
        return res;
    }

    @Override
    public String aliAppCallback(HttpServletRequest requests) {
        //1.从支付宝回调的request域中取值
        Map<String, String[]> requestParams = requests.getParameterMap();
        Map<String, String> params = new HashMap<>();
        System.out.println("从支付宝回调的request域中取值:requestParams===================================" + requestParams);
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        // 2.封装必须参数
        // 商户订单号
        String outTradeNo = requests.getParameter("out_trade_no");
        System.err.println("out_trade_no==================================" + outTradeNo);
        String orderType = requests.getParameter("body"); // 订单内容
        System.out.println("orderType==================================" + orderType);
        String tradeStatus = requests.getParameter("trade_status"); // 交易状态
        System.err.println("tradeStatus=================================" + tradeStatus);
        //查询订单信息
        GoodOrder order = goodOrderService.findByOrderNo(outTradeNo);
        if (order == null) {
            return "success";
        }
        //成功订单
        if (!StringUtils.equals(tradeStatus, "WAIT_BUYER_PAY")) {
            if (StringUtils.equals(tradeStatus, "TRADE_SUCCESS") || StringUtils.equals(tradeStatus, "TRADE_FINISHED")) {
                if (order.getPayState() == 0) {
                    //修改订单状态
                    order.setStatus(2);
                    order.setPayType(1);
                    order.setPayState(2);
                    goodOrderService.update(order);
                }
            }
            if (StringUtils.equals(tradeStatus, "TRADE_CLOSED")) {
                return "success";
            }
        } else {
            return "error";
        }
        // 只处理支付成功的订单:修改交易表状态,支付成功
        return "success";
    }
}
